// Copyright (c) Microsoft Corporation. 
// Licensed under the MIT license.

#pragma once

#include "CoreMinimal.h"
#include "SimplygonJobData.h"
#include "IMeshReductionInterfaces.h"

class FSimplygonPluginMeshReductionModule;

/**
 * @brief The Simplygon Reduction interface which implements IMeshMerging, IMeshReduction inferfaces
*/
class ISimplygonReduction : public IMeshMerging, public IMeshReduction, public FTickerObjectBase
{
	public:
	/**
	 * Asynchronously process the scene using the given pipeline. The job data object
	 * and contained data must remain valid until the async method completes.
	 * To reduce a single static mesh, add it to a scene, call this method and collect the result
	 * from the pipeline output scene using the simplygon data converter helper methods. See the
	 * LODRecipe flow for an example on how to use the async interface.
	 * @param SceneToProcess Input scene for processing.
	 * @param Pipeline Pipeline to use
	 * @param JobData Job data including meshes to reduce, material baking data and job GUID
	 * @param ProgressDelegate Callback for progress.
	 * @param CompleteDelegate Callback for process completion.
	 * @param FailedDelegate Callback for process failure.
	 */
	virtual void RunSceneAsync(Simplygon::spScene SceneToProcess,
		Simplygon::spPipeline Pipeline,
		const FSimplygonJobData& JobData,
		const FSimplygonProcessProgressDelegate& ProgressDelegate,
		const FSimplygonProcessCompleteDelegate& CompleteDelegate,
		const FSimplygonProcessFailedDelegate& FailedDelegate) = 0;

	/**
	 * Asynchronously process the batch of scenes using the given pipelines. The job data object
	 * and contained data must remain valid until the async method completes.
	 * Add all scenes and pipelines to process to the batch, call this method and collect the result
	 * from the pipelines output scene using the simplygon data converter helper methods. See the
	 * LODRecipe flow for an example on how to use the async interface.
	 * @param SceneToProcess Input scene for processing.
	 * @param Pipeline Pipeline to use
	 * @param JobData Job data including meshes to reduce, material baking data and job GUID
	 * @param ProgressDelegate Callback for progress.
	 * @param CompleteDelegate Callback for process completion.
	 * @param FailedDelegate Callback for process failure.
	 */
	virtual void RunBatchAsync(Simplygon::spPipelineBatch Batch,
		const FSimplygonJobData& JobData,
		const FSimplygonProcessProgressDelegate& ProgressDelegate,
		const FSimplygonProcessBatchCompleteDelegate& CompleteDelegate,
		const FSimplygonProcessFailedDelegate& FailedDelegate) = 0;

	virtual FSimplygonUpdateNavMeshVisibilitySamplesDelegate GetNavmeshVisibilitySamplerUpdateHandler() = 0;
	virtual TArray<FVector> GetNavMeshVisibilitySamples() const = 0;
	virtual void ClearNavmeshSamples() = 0;

	virtual FSimplygonUpdateCuttingPlanesDelegate GetCuttingPlaneUpdateHandler() = 0;
	virtual TArray<FPlane> GetClippingPlanes() const = 0;
	virtual void ClearClippingPlane() = 0;

	virtual bool IsUsingDistribution() const = 0;
	virtual bool IsUsingIncrediBuild() const = 0;

	virtual bool IsUsingDistributedMeshMerging() const = 0;

private:

	/**
	 * @brief Create SimplygonReducion module
	 * @return A valid pointer to a concrete implementation of ISimplygonReduction interface
	*/
	static ISimplygonReduction* Create(bool bUseDistributedMeshMerging = false);

	friend class FSimplygonPluginMeshReductionModule;
};
